/* Copyright 2008 Bas van den Berg
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <string>

#include "yaffut.h"
#include "myassert.h"
#include "TestSession.h"

#include "CmdVisitor.h"
#include "MudObject.h"
#include "MudContainer.h"
#include "MudCreature.h"
#include "MudDoor.h"
#include "MudConsumable.h"
#include "MudCredits.h"
#include "MudExit.h"
#include "MudItem.h"
#include "MudMobile.h"
#include "MudKey.h"
#include "MudOpenable.h"
#include "MudPlayer.h"
#include "MudWearable.h"
#include "ElevatorController.h"
#include "Room.h"
#include "Area.h"

using namespace std;
using namespace Chronos;

struct CmdVisitorTest {
};


TEST(CmdVisitorTest, testMudContainer) {
	MudContainer container("container", "");
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(container));
	ASSERT_NOT_NULL(TypeVisitor<MudContainer>::getType(container));
}


TEST(CmdVisitorTest, testMudOpenableContainer) {
	MudOpenableContainer container("container", "", 1);
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(container));
	ASSERT_NOT_NULL(TypeVisitor<MudContainer>::getType(container));
    ASSERT_NOT_NULL(TypeVisitor<MudOpenable>::getType(container));
}


TEST(CmdVisitorTest, testMudItem) {
	MudItem item(0, "item", "", 1);
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(item));
	ASSERT_NOT_NULL(TypeVisitor<MudItem>::getType(item));
}


TEST(CmdVisitorTest, testMudDrink) {
    MudDrink drink(0, "drink", "", 1, 0);
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(drink));
	ASSERT_NOT_NULL(TypeVisitor<MudDrink>::getType(drink));
    ASSERT_NOT_NULL(TypeVisitor<MudConsumable>::getType(drink));
	ASSERT_NOT_NULL(TypeVisitor<MudItem>::getType(drink));
}


TEST(CmdVisitorTest, testMudFood) {
    MudFood food(0, "food", "", 1, 0);
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(food));
	ASSERT_NOT_NULL(TypeVisitor<MudFood>::getType(food));
    ASSERT_NOT_NULL(TypeVisitor<MudConsumable>::getType(food));
	ASSERT_NOT_NULL(TypeVisitor<MudItem>::getType(food));
}


TEST(CmdVisitorTest, testMudCredits) {
    MudCredits credits(0, "credits", "", 1);
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(credits));
	ASSERT_NOT_NULL(TypeVisitor<MudItem>::getType(credits));
	ASSERT_NOT_NULL(TypeVisitor<MudCredits>::getType(credits));
}


TEST(CmdVisitorTest, testMudWearable) {
    MudWearable wearable(0, "clothes", "", 1, Equipment::head);
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(wearable));
	ASSERT_NOT_NULL(TypeVisitor<MudItem>::getType(wearable));
	ASSERT_NOT_NULL(TypeVisitor<MudWearable>::getType(wearable));
}


TEST(CmdVisitorTest, testMudKey) {
    MudKey key(0, "key", "", 1);
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(key));
	ASSERT_NOT_NULL(TypeVisitor<MudItem>::getType(key));
	ASSERT_NOT_NULL(TypeVisitor<MudKey>::getType(key));
}


TEST(CmdVisitorTest, testMudExit) {
    Area area(0, "");
	MudRoomExit mudRoomExit("north", "", "", "", "", area, 1);
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(mudRoomExit));
	ASSERT_NOT_NULL(TypeVisitor<MudExit>::getType(mudRoomExit));
}


TEST(CmdVisitorTest, testMudDoor) {
    Area area(0, "");
    MudDoor door("door", "", new RoomPortal(area, 1, "", "", ""), 10);
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(door));
	ASSERT_NOT_NULL(TypeVisitor<MudDoor>::getType(door));
	ASSERT_NOT_NULL(TypeVisitor<MudExit>::getType(door));
	ASSERT_NOT_NULL(TypeVisitor<MudOpenable>::getType(door));
}


TEST(CmdVisitorTest, testMudCreature) {
	MudCreature creature("creature", "", 1, 2, 3, 4);
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(creature));
	ASSERT_NOT_NULL(TypeVisitor<MudCreature>::getType(creature));
	ASSERT_NOT_NULL(TypeVisitor<MudMobile>::getType(creature));
}


TEST(CmdVisitorTest, testMudPlayer) {
	TestSession session("player");
	MudObject* obj = &session.getPlayer();
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(*obj));
	ASSERT_NOT_NULL(TypeVisitor<MudPlayer>::getType(*obj));
	ASSERT_NOT_NULL(TypeVisitor<MudMobile>::getType(*obj));
}


TEST(CmdVisitorTest, testElevatorButton) {
	Room elevator("elevator", "");	
	Area area(0, "");
	MudRoomExit* in = new MudRoomExit("in", "", "", "", "", area, 0);
	ElevatorController controller(elevator, in, area);
	MudObject* obj = new ElevatorButton("button", controller, 0);
	ASSERT_NOT_NULL(TypeVisitor<MudObject>::getType(*obj));
	ASSERT_NOT_NULL(TypeVisitor<ElevatorButton>::getType(*obj));
	delete obj;
}

